import e from "jquery";
import t from "./mat3";
import n from "./rect";
import r from "./vec2";
import i from "./paths";
import s from "./animate";
import o from "./color";
import u from "./event";
import a from "./event_center";
import f from "./touch";
import l from "./touch_event";
import c from "./scale_mode";
import h from "./align_mode";

class View {
  static viewIndex = 0;
  static issueViewName(e) {
    let t = e + "_" + this.viewIndex;
    return (this.viewIndex += 1), t;
  }
  className = "AXEView";
  controller = null;
  dealloc() {
    let e = this;
    (e._matrix = null), (e._mask = null), e.remove(), a.removeListener(e);
  }
  clone() {
    let e = this,
      t = new View();
    return e.copyProperties(t), t;
  }
  copyProperties(e) {
    let t = this;
    e.name(t.name()),
      e.width(t.width()),
      e.height(t.height()),
      e.alpha(t.alpha()),
      e.scaleMode(t.scaleMode()),
      e.alignMode(t.alignMode()),
      t.bgColor() != null && e.bgColor(t.bgColor().clone()),
      t.shadowColor() != null && e.shadowColor(t.shadowColor().clone()),
      e.shadowOffsetX(t.shadowOffsetX()),
      e.shadowOffsetY(t.shadowOffsetY()),
      e.shadowBlur(t.shadowBlur()),
      e.blendMode(t.blendMode()),
      e.enabled(t.enabled()),
      e.visible(t.visible()),
      e.clip(t.clip()),
      t.mask() != null && e.mask(t.mask().clone()),
      e.matrix(t.matrix());
  }
  updatePropsFromXML(e) {
    let n = this;
    n.name(e.is("[name]") ? e.attr("name") : null),
      n.width(e.is("[width]") ? parseFloat(e.attr("width")) : 0),
      n.height(e.is("[height]") ? parseFloat(e.attr("height")) : 0),
      n.alpha(e.is("[alpha]") ? parseFloat(e.attr("alpha")) : 1),
      e.is("[sat]") && n.saturation(parseFloat(e.attr("sat"))),
      e.is("[bg-color]") && n.bgColor(o.colorWithString(e.attr("bg-color"))),
      e.is("[shadow-color]") &&
        n.shadowColor(o.colorWithString(e.attr("shadow-color"))),
      e.is("[shadow-x]") && n.shadowOffsetX(parseFloat(e.attr("shadow-x"))),
      e.is("[shadow-y]") && n.shadowOffsetY(parseFloat(e.attr("shadow-y"))),
      e.is("[shadow-blur]") &&
        n.shadowBlur(parseInt(e.attr("shadow-blur"), 10)),
      n.blendMode(e.is("blend") ? e.attr("blend") : n._blendMode),
      n.enabled(e.is("[enabled]") ? e.attr("enabled") == "true" : !0),
      n.visible(
        e.is("[visible]")
          ? String(e.attr("visible")).toLowerCase() === "true"
          : !0
      ),
      n.clip(
        e.is("[clip]") ? String(e.attr("clip")).toLowerCase() === "true" : !1
      );
    let r = e.find("> mask");
    if (r.length > 0) {
      let s = new i();
      s.addCommand(r.text()), n.mask(s);
    } else n.mask(null);
    let u = new t();
    if (e.is("[matrix]")) {
      let a = e.attr("matrix").split(",");
      (u.a = parseFloat(a[0])),
        (u.b = parseFloat(a[1])),
        (u.c = parseFloat(a[2])),
        (u.d = parseFloat(a[3])),
        (u.tx = parseFloat(a[4])),
        (u.ty = parseFloat(a[5]));
    } else {
      let f = e.is("[scale-x]") ? parseFloat(e.attr("scale-x")) : 1,
        l = e.is("[scale-y]") ? parseFloat(e.attr("scale-y")) : 1,
        p = e.is("[rotation]")
          ? parseFloat(e.attr("rotation")) * (Math.PI / 180)
          : 0,
        d = e.is("[x]") ? parseFloat(e.attr("x")) : 0,
        v = e.is("[y]") ? parseFloat(e.attr("y")) : 0;
      (u.a = f * Math.cos(p)),
        (u.b = Math.sin(p)),
        (u.c = -1 * Math.sin(p)),
        (u.d = l * Math.cos(p)),
        (u.tx = d),
        (u.ty = v);
    }
    n.matrix(u);
    if (e.is("[align]")) {
      let m = h[e.attr("align")];
      n.alignMode(m);
    }
    if (e.is("[scale-mode]")) {
      let g = e.attr("scale-mode");
      typeof c[g] == "function" && n.scaleMode(c[g]);
    }
    n.controller != null && n.controller.onViewUpdateFromXML(e);
  }
  cachedImage = null;
  _name = null;
  name(e?) {
    let t = this;
    return (
      arguments.length > 0 && (t._name = e),
      t._name == null && (t._name = View.issueViewName(t.className)),
      t._name
    );
  }
  pathname() {
    let e = this,
      t = [],
      n = e;
    do t.unshift(n.name()), (n = n.parent());
    while (n != null);
    return t.join(".");
  }
  _needToRender = !1;
  needToRender(e?) {
    let t = this;
    return (
      arguments.length > 0 && e != t._needToRender && (t._needToRender = e),
      t._needToRender
    );
  }
  _scaleMode = null;
  scaleMode(e?) {
    let t = this;
    if (arguments.length > 0 && t._scaleMode != e) {
      t._scaleMode = e;
      let n: any = t.stage();
      n != null && t.resize(n.stageWidth(), n.stageHeight());
    }
    return t._scaleMode;
  }
  _alignMode = null;
  alignMode(e?) {
    let t = this;
    if (arguments.length > 0 && t._alignMode != e) {
      t._alignMode = e;
      let n: any = t.stage();
      n != null && t.resize(n.stageWidth(), n.stageHeight());
    }
    return t._alignMode;
  }
  x(e) {
    let t = this;
    if (arguments.length > 0) {
      let n = t.matrix().clone();
      (n.tx = e), t.matrix(n);
    }
    return t.matrix().tx;
  }
  y(e) {
    let t = this;
    if (arguments.length > 0) {
      let n = t.matrix().clone();
      (n.ty = e), t.matrix(n);
    }
    return t.matrix().ty;
  }
  scaleX(e) {
    let t = this,
      n = t.matrix(),
      r = t.radian(),
      i = n.a / Math.cos(r);
    return (
      arguments.length > 0 &&
        ((i = e), (n = n.clone()), (n.a = i * Math.cos(r)), t.matrix(n)),
      i
    );
  }
  scaleY(e) {
    let t = this,
      n = t.matrix(),
      r = t.radian(),
      i = n.d / Math.cos(r);
    return (
      arguments.length > 0 &&
        ((i = e), (n = n.clone()), (n.d = i * Math.cos(r)), t.matrix(n)),
      i
    );
  }
  rotation(e) {
    let t = this,
      n = 0;
    if (arguments.length > 0) {
      n = e;
      let r = e * (Math.PI / 180);
      t.radian(r);
    } else n = t.radian() * (180 / Math.PI);
    return n;
  }
  radian(e?) {
    let t = this,
      n = t.matrix(),
      r = Math.asin(n.b);
    n.b > 0 && n.a < 0
      ? (r = Math.PI - r)
      : n.b < 0 && n.a < 0
      ? (r = Math.PI - r)
      : n.b < 0 && n.a > 0 && (r = Math.PI * 2 + r);
    if (arguments.length > 0) {
      let i = n.a / Math.cos(r);
      (r = e),
        (n = n.clone()),
        (n.a = i * Math.cos(r)),
        (n.b = Math.sin(r)),
        (n.c = -1 * n.b),
        (n.d = n.a),
        t.matrix(n);
    }
    return r;
  }
  _matrix = null;
  matrix(e?) {
    let n = this;
    return (
      arguments.length > 0 && ((n._matrix = e.clone()), n.needToRender(!0)),
      n._matrix == null && (n._matrix = new t()),
      n._matrix
    );
  }
  _width = 0;
  width(e?) {
    let t = this;
    return (
      isNaN(e) == 0 && t._width != e && ((t._width = e), t.needToRender(!0)),
      t._width
    );
  }
  _height = 0;
  height(e?) {
    let t = this;
    return (
      isNaN(e) == 0 && t._height != e && ((t._height = e), t.needToRender(!0)),
      t._height
    );
  }
  _alpha = 1;
  alpha(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        t._alpha != e &&
        ((t._alpha = e), t.needToRender(!0)),
      t._alpha
    );
  }
  _saturation = 1;
  saturation(e) {
    let t = this;
    return (
      isNaN(e) == 0 &&
        ((e = Math.max(0, Math.min(1, e))),
        e != t._saturation && ((t._saturation = e), t.needToRender(!0))),
      t._saturation
    );
  }
  _bgColor = null;
  bgColor(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        ((t._bgColor = Boolean(e) ? e.clone() : null), t.needToRender(!0)),
      t._bgColor
    );
  }
  _clip = !1;
  clip(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        e != t._clip &&
        ((t._clip = e), t.needToRender(!0)),
      t._clip
    );
  }
  _mask = null;
  mask(e?) {
    let t = this;
    return arguments.length > 0 && ((t._mask = e), t.needToRender(!0)), t._mask;
  }
  _shadowOffsetX = 0;
  shadowOffsetX(e?) {
    let t = this;
    return (
      isNaN(parseFloat(e)) === !1 &&
        parseFloat(e) != t._shadowOffsetX &&
        ((t._shadowOffsetX = parseFloat(e)), t.needToRender(!0)),
      t._shadowOffsetX
    );
  }
  _shadowOffsetY = 0;
  shadowOffsetY(e?) {
    let t = this;
    return (
      isNaN(parseFloat(e)) === !1 &&
        parseFloat(e) != t._shadowOffsetY &&
        ((t._shadowOffsetY = parseFloat(e)), t.needToRender(!0)),
      t._shadowOffsetY
    );
  }
  _shadowColor = null;
  shadowColor(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        typeof e == "object" &&
        ((t._shadowColor = e), t.needToRender(!0)),
      t._shadowColor
    );
  }
  _shadowBlur = 0;
  shadowBlur(e?) {
    let t = this;
    return (
      arguments.length > 0 &&
        isNaN(parseInt(e, 10)) === !1 &&
        parseInt(e, 10) != t._shadowBlur &&
        ((t._shadowBlur = e), t.needToRender(!0)),
      t._shadowBlur
    );
  }
  _blendMode = "source-over";
  blendMode(e?) {
    let t = this;
    return (
      typeof e == "string" && ((t._blendMode = e), t.needToRender(!0)),
      t._blendMode
    );
  }
  _visible = !0;
  visible(e?) {
    let t = this;
    return (
      typeof e == "boolean" &&
        e != t._visible &&
        ((t._visible = e), t.needToRender(!0)),
      t._visible
    );
  }
  _parent = null;
  parent(e?) {
    let t = this;
    return arguments.length > 0 && (t._parent = e), t._parent;
  }
  remove() {
    let e = this;
    e.parent() != null && e.parent().removeSubView(e);
  }
  _enabled = !0;
  enabled(e?) {
    let t = this;
    return (
      typeof e == "boolean" &&
        e != t._enabled &&
        ((t._enabled = e), (t.lastEvent = null)),
      t._enabled
    );
  }
  matrixTo(e?) {
    let n = this,
      r = null;
    if (arguments.length > 0) {
      let i = e,
        s = new t(),
        o = new t();
      while (i != null && r == null) {
        let u = n;
        while (u != null) {
          if (i == u) {
            let a = o.inversion();
            r = s.concatWith(a);
            break;
          }
          (s = s.concatWith(u.matrix())), (u = u.parent());
        }
        (o = o.concatWith(i.matrix())), (i = i.parent());
      }
    } else r = new t();
    return r;
  }
  rect(e) {
    let t = this,
      i = new r(0, 0),
      s = new r(t.width(), 0),
      o = new r(0, t.height()),
      u = new r(t.width(), t.height()),
      a = arguments.length > 0 ? t.matrixTo(e) : t.matrixTo(),
      f = null;
    if (a != null) {
      let l = a.transformPoint(i),
        c = a.transformPoint(s),
        h = a.transformPoint(o),
        p = a.transformPoint(u),
        d = Math.min(l.x, c.x, h.x, p.x),
        v = Math.max(l.x, c.x, h.x, p.x),
        m = Math.min(l.y, c.y, h.y, p.y),
        g = Math.max(l.y, c.y, h.y, p.y);
      f = new n(d, m, v - d, g - m);
    }
    return f;
  }
  convertTouches(e) {
    let t = this,
      n = [],
      i = t.matrixTo(e.target);
    for (let s = 0; s < e.touches.length; s++) {
      let o = new r(e.touches[s].x, e.touches[s].y);
      o = i.inversePoint(o);
      let u = new f(o.x, o.y, e.touches[s].stageX, e.touches[s].stageY);
      n.push(u);
    }
    return n;
  }
  lastEvent = null;
  startEvent = null;
  triggerEvent(e) {
    let t = this,
      n = !1;
    if (t.enabled() && t.visible()) {
      let i = t.animating();
      if (e.type == l.TOUCH_START) {
        let s = t.rect(e.target),
          o = e.touches[0],
          u = new r(o.x, o.y);
        if (t.className == "AXEStage" || s.containsVec2(u))
          (n = !0),
            i === !1 &&
              ((t.lastEvent = new l(t, e.type, t.convertTouches(e))),
              (t.startEvent = t.lastEvent),
              a.dispatchEvent(t.lastEvent));
      } else if (e.type == l.TOUCH_MOVE)
        t.lastEvent != null &&
          ((n = !0),
          (t.lastEvent = new l(t, e.type, t.convertTouches(e))),
          a.dispatchEvent(t.lastEvent));
      else if (e.type == l.TOUCH_END && t.lastEvent != null) {
        let f = t.lastEvent,
          c = t.startEvent;
        (t.lastEvent = null),
          (t.startEvent = null),
          (n = !0),
          a.dispatchEvent(new l(t, e.type, [])),
          f.type == l.TOUCH_START &&
            a.dispatchEvent(new l(t, l.CLICK, f.touches));
        if (
          f.type == l.TOUCH_MOVE &&
          f.timeStamp - c.timeStamp < 500 &&
          f.touches.length <= 1 &&
          c.touches.length <= 1
        ) {
          let h = new r(c.touches[0].stageX, c.touches[0].stageY),
            p = new r(f.touches[0].stageX, f.touches[0].stageY);
          h.distance(p) > 30 &&
            Math.abs(c.timeStamp - f.timeStamp) < 500 &&
            a.dispatchEvent(new l(t, l.SWIPE, [c.touches[0], f.touches[0]]));
        }
      }
    }
    return n;
  }
  animateChangeFlag = !1;
  objAnimate = null;
  _animating = !1;
  animating(e?) {
    let t = this;
    typeof e == "boolean" && (t._animating = e);
    let n = t._animating;
    return n === !1 && t.parent() != null && (n = t.parent().animating()), n;
  }
  animate(e, t, n, r, i) {
    let o = this;
    (o.objAnimate = new s(o, e, t, n, r, i)), (o.animateChangeFlag = !0);
  }
  stopAnimation(e?) {
    let t = this;
    t.objAnimate != null &&
      ((e = arguments.length >= 1 ? e : !1),
      t._animating && e && t.objAnimate.jumpToEnd(),
      t.animating(!1),
      (t.animateChangeFlag = !1),
      (t.objAnimate = null),
      t.onAnimationStop());
  }
  onAnimationStart() {
    let e = this;
    e.controller != null && e.controller.onViewStartAnimate();
    let t = new u(e, u.ANIMATION_BEGIN);
    a.dispatchEvent(t);
  }
  onAnimationStop() {
    let e = this;
    e.controller != null && e.controller.onViewEndAnimate();
    let t = new u(e, u.ANIMATION_END);
    a.dispatchEvent(t);
  }
  onAdd(e) {
    let t = this;
    t.controller != null && t.controller.onViewAdded(e);
    let n = new u(t, u.ADDED);
    a.dispatchEvent(n);
  }
  removeFromStage() {
    let e = this;
    (e.lastEvent = null),
      (e.startEvent = null),
      e.controller != null && e.controller.onViewRemoveFromStage();
    let t = new u(e, u.REMOVE_FROM_STAGE);
    a.dispatchEvent(t);
  }
  onRemoveFromSuperView(e) {
    let t = this;
    (t.lastEvent = null),
      (t.startEvent = null),
      t.controller != null && t.controller.onViewRemoved(e);
    let n = new u(t, u.REMOVED);
    a.dispatchEvent(n), t.removeFromStage();
  }
  stage() {
    let e = this;
    while (e != null && e.className != "AXEStage") e = e.parent();
    return e;
  }
  onStage = !1;
  onAddToStage() {
    let e = this;
    (e.onStage = !0),
      (e.lastEvent = null),
      (e.startEvent = null),
      e.controller != null && e.controller.onViewAddToStage();
    let t = new u(e, u.ADD_TO_STAGE);
    a.dispatchEvent(t);
    let n: any = e.stage();
    n != null &&
      (e.onWindowOrientationChanged(n.orientation),
      e.resize(n.stageWidth(), n.stageHeight()));
  }
  onWindowOrientationChanged(e) {
    let t = this;
    t.windowOrientationChange(e),
      t.controller != null && t.controller.onWindowOrientationChanged(e);
  }
  windowOrientationChange(e) {}
  _active = !0;
  active(e) {
    let t = this;
    return (
      e != undefined &&
        t._active != e &&
        ((t._active = e),
        t._active
          ? (t.onActivate(),
            t.controller != null && t.controller.onViewActivate())
          : (t.onDeactivate(),
            t.controller != null && t.controller.onViewDeactivate())),
      t._active
    );
  }
  onActivate() {}
  onDeactivate() {}
  resize(e, t) {
    let n = this;
    if (n.alignMode() != null && n.scaleMode() != null) {
      let r = n.alignMode(),
        i = n.scaleMode(),
        s = i(n.width(), n.height(), e, t, r);
      n.matrix(s);
    }
    n.controller != null && n.controller.onViewResize(e, t);
    let o = new u(n, u.RESIZE);
    a.dispatchEvent(o);
  }
  update(e, t) {
    let n = this;
    n.animateChangeFlag &&
      ((n.animateChangeFlag = !1),
      n.objAnimate != null &&
        (n.objAnimate.init(e), n.animating(!0), n.onAnimationStart()));
    if (n.objAnimate != null) {
      let r = n.objAnimate.update(e);
      r && ((n.objAnimate = null), n.animating(!1), n.onAnimationStop());
    }
    n.controller != null && n.controller.onViewUpdated(e, t),
      n.needToRender() && (n.cachedImage = null);
  }
}

export default View;
